package com.cskaoyan.order.service.impl;

import com.cskaoyan.mall.commons.exception.ExceptionProcessorUtils;
import com.cskaoyan.mall.constant.ShoppingRetCode;
import com.cskaoyan.mall.order.constant.OrderRetCode;
import com.cskaoyan.mall.order.dto.PayOrderSuccessRequest;
import com.cskaoyan.mall.order.dto.PayOrderSuccessResponse;
import com.cskaoyan.order.biz.TransOutboundInvoker;
import com.cskaoyan.order.biz.context.AbsTransHandlerContext;
import com.cskaoyan.order.biz.factory.OrderProcessPipelineFactory;
import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.OrderShipping;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.OrderShippingMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import com.cskaoyan.order.dto.*;
import com.cskaoyan.order.form.OrderDetail;
import com.cskaoyan.order.service.OrderCoreService;
import com.cskaoyan.order.utils.GlobalIdGeneratorUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;

import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class OrderCoreServiceImpl implements OrderCoreService {

    private static final Integer STOCK_FREE = 2;
    private static final Integer ORDER_CANCEL_STATUS = 7;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderItemMapper orderItemMapper;

    @Autowired
    OrderShippingMapper orderShippingMapper;

    @Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

    @Autowired
    StockMapper stockMapper;


    /**
     * 创建订单的处理流程
     *
     * @param request
     * @return
     */
    @Override
    public CreateOrderResponse createOrder(CreateOrderRequest request) {
        CreateOrderResponse response = new CreateOrderResponse();
        try {
            //创建pipeline对象
            TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

            //启动pipeline
            invoker.start(); //启动流程（pipeline来处理）

            //获取处理结果
            AbsTransHandlerContext context = invoker.getContext();

            //把处理结果转换为response
            response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);

        } catch (Exception e) {
            log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    @Override
    public CancelOrderResponse cancelOrder(CancelOrderRequest request) {
        CancelOrderResponse cancelOrderResponse = new CancelOrderResponse();

        try {
            request.requestCheck();

            // 将订单的状态码改为7、更新订单的更新时间
            orderMapper.updateStatusAndUpdateTime(ORDER_CANCEL_STATUS, new Date(), request.getOrderId());

            // 将订单的库存锁定状态码改为2
            orderItemMapper.updateStockStatus(STOCK_FREE, request.getOrderId());
            // 查询出订单所对应的商品，需要商品id和商品数量
            List<OrderItem> orderItems = orderItemMapper.queryByOrderId(request.getOrderId());

            for (OrderItem orderItem : orderItems) {
                Long itemId = orderItem.getItemId();
                Integer num = orderItem.getNum();

                Stock stock = new Stock();
                stock.setItemId(itemId);
                stock.setStockCount((long) num);
                stock.setLockCount(0 - num);

                // 更新stock表中的商品库存数量
                stockMapper.updateStock(stock);

                cancelOrderResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
                cancelOrderResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(cancelOrderResponse, e);
        }

        return cancelOrderResponse;
    }

    @Override
    public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
        DeleteOrderResponse response = new DeleteOrderResponse();
        try {
            request.requestCheck();
            String orderId = request.getOrderId();
            Order order = orderMapper.selectByPrimaryKey(orderId);
            if (order.getStatus() == 0) {
                List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
                for (OrderItem orderItem : orderItems) {
                    Stock stock = new Stock();
                    stock.setItemId(orderItem.getItemId());
                    stock.setStockCount(((long) orderItem.getNum()));
                    stock.setLockCount(-orderItem.getNum());
                    stockMapper.updateStock(stock);
                }
            }
            orderMapper.deleteByPrimaryKey(orderId);
            orderItemMapper.deleteByOrderId(orderId);
            orderShippingMapper.deleteByOrderId(orderId);
            response.setResult("成功");
        } catch (Exception e) {
            e.printStackTrace();
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        response.setCode(OrderRetCode.SUCCESS.getCode());
        response.setMsg(OrderRetCode.SUCCESS.getMessage());
        return response;
    }

    /**
     * 查找订单详情
     *
     * @param request
     * @return
     */
    @Override
    public OrderDetail searchOrderDetail(OrderDetailRequest request) {

        // 查表获取数据
        // 订单数据
        Order order = orderMapper.selectByPrimaryKey(request.getOrderId());
        // 获取订单商品信息
        List<OrderItem> orderItems = orderItemMapper.queryByOrderId(request.getOrderId());
        // 订单商品数量信息
        Stock stock = stockMapper.selectStock(Long.parseLong(request.getOrderId()));
        // 用户和地址信息
        OrderShipping orderShipping = orderShippingMapper.selectByPrimaryKey(request.getOrderId());


        // 参数封装(可使用Converter)
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setUserName(orderShipping.getReceiverName());
        orderDetail.setOrderTotal(order.getPayment());
        orderDetail.setUserId(order.getUserId());
        List<OrderItemDto> orderItemDtos = new LinkedList<>();
        // 此处可以使用converter
        for (OrderItem orderItem : orderItems) {
            OrderItemDto orderItemDto = new OrderItemDto();
            orderItemDto.setId(orderItem.getId());
            orderItemDto.setItemId(orderItem.getItemId().toString());
            orderItemDto.setOrderId(orderItem.getOrderId());
            orderItemDto.setNum(orderItem.getNum());
            orderItemDto.setPicPath(orderItem.getPicPath());
            orderItemDto.setPrice(BigDecimal.valueOf(orderItem.getPrice()));
            orderItemDto.setTitle(orderItem.getTitle());
            orderItemDto.setTotalFee(BigDecimal.valueOf(orderItem.getTotalFee()));
            orderItemDto.setOrderStatus(orderItem.getStatus());
            orderItemDtos.add(orderItemDto);
        }
        orderDetail.setGoodsList(orderItemDtos);
        orderDetail.setOrderStatus(order.getStatus());
        orderDetail.setStreetName(orderShipping.getReceiverAddress());
        orderDetail.setTel(orderShipping.getReceiverMobile());

        return orderDetail;
    }

    @Override
    public PayOrderSuccessResponse payOrderSuccess(PayOrderSuccessRequest request) {

        String orderId = request.getOrderId();
        orderMapper.updateStatusAndUpdateTime(OrderConstants.ORDER_STATUS_PAYED, new Date(), orderId);
        List<OrderItem> orderItems = orderItemMapper.queryByOrderId(orderId);
        for (OrderItem orderItem : orderItems) {
            Stock stock = new Stock();
            stock.setItemId(orderItem.getItemId());
            stock.setLockCount(-orderItem.getNum());
            stockMapper.updateStock(stock);
        }
        PayOrderSuccessResponse payOrderSuccessResponse = new PayOrderSuccessResponse();
        payOrderSuccessResponse.setCode(OrderRetCode.SUCCESS.getCode());
        payOrderSuccessResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
        return payOrderSuccessResponse;
    }
}
